package com.cold.legendary.bprocess.context.manager.helper;

import com.cold.legendary.bprocess.common.constance.BErrorCodeEnum;
import com.cold.legendary.bprocess.common.exception.BProcessException;
import com.cold.legendary.bprocess.context.def.BPointDef;
import com.cold.legendary.bprocess.context.ins.BArrowIns;
import com.cold.legendary.bprocess.context.ins.BPointIns;
import com.cold.legendary.bprocess.definition.process.dto.BPointDefDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * @author cold
 * @since 2023/3/10
 */
@Slf4j
public class BPHelper {

    public static BPointIns createBPointIns(BPointDef bPointDef, BArrowIns nextBArrowIns) {
        return BPointIns.builder()
                .pointTagEnum(bPointDef.getPointTagEnum())
                .nextBArrowIns(nextBArrowIns)
                .pointId(bPointDef.getPointId())
                .pointName(bPointDef.getPointName())
                .callWayEnum(bPointDef.getCallWayEnum())
                .bPointService(bPointDef.getBPointService())
                .build();
    }


    public static BArrowIns createBArrowIns(BPointIns nextBPointIns) {
        if (null == nextBPointIns) {
            return null;
        }
        return BArrowIns.builder()
                .nextBPointIns(nextBPointIns)
                .build();
    }


    public static Stack<BPointDef> buildBPointDefStack(String processId, List<BPointDefDto> bPointDefDtos, Map<String, BPointDef> bPointDefMap) {
        Stack<BPointDef> stack = new Stack<>();
        for (BPointDefDto bPointDefDto : bPointDefDtos) {
            if (StringUtils.isEmpty(bPointDefDto.getPointId())) {
                log.error("检测到process定义中,PointId为空!请检查流程定义@BProcess的类!processId={}", processId);
                throw new BProcessException(BErrorCodeEnum.SYS_BPROCESS_NONE_BPOINT_ERROR);
            }
            BPointDef bPointDef = bPointDefMap.get(bPointDefDto.getPointId());
            if (null == bPointDef) {
                log.error("检测到process定义中的PointId无合法的@BPoint注解实现类!请实现或者流程定义中去掉此PointId!" +
                        " processId={}, pointId={}", processId, bPointDefDto.getPointId());
                throw new BProcessException(BErrorCodeEnum.SYS_BPROCESS_BPOINT_NO_IMPL_ERROR);
            }

            stack.push(bPointDef);
        }
        return stack;
    }
}
